/**
 * @file score_engine.c
 * @brief 评分引擎对外接口实现
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "score_engine.h"
#include "preprocess.h"
#include "feature_extractor.h"
#include "calculate_score.h"
#include "base_file_parser.h"
#include "log.h"

// 添加打印宏，方便添加前缀
//#define SE_PRINT(fmt, ...) printf("ScoreEngine: " fmt, ##__VA_ARGS__)
//#define SE_ERROR(fmt, ...) fprintf(stderr, "ScoreEngine-ERROR: " fmt, ##__VA_ARGS__)

// 定义静态错误码变量
static int last_error_code = ERROR_SUCCESS;

// 设置错误码
static void set_error(int error_code) {
    last_error_code = error_code;
}

// 内部状态结构体定义
typedef struct {
    // 配置信息
    int sample_rate;
    int frame_size;
    ScoreEngineConfig config;
    
    // 算法缓存
    void* algorithm_state;
    
    // 评分缓存
    float* feature_buffer;
    int buffer_size;
    int current_frame;
    
    // 特征缓冲区 - 用于存储整首歌的所有帧特征
    ScoreFeatureBuffers* buffers;  // 封装的特征缓冲区
    
    // 前一帧线性幅度谱，用于计算频谱通量
    float* prev_spectrum_mag;  // 缓存前一帧线性幅度谱
    
    // 基准文件解析信息
    void* base_file_cache;
    BaseFileHeader file_header;  // Parsed file header
    int total_frames;            // Total frames in base file
    
    // 帧处理缓存 - 用于存储上一个半帧数据
    float* prev_half_frame;      // 上一个半帧数据缓存
    int has_prev_frame;          // 是否有上一帧数据的标志
    
    // 完整帧缓冲区 - 用于存储完整帧数据
    float* full_frame;           // 完整帧缓冲区
    
    // 特征集缓存 - 用于存储提取的特征
    FeatureSet* features;        // 特征集缓存
} InternalState;

// 初始化评分引擎
ScoreEngine* init_score_engine(const void* base_file, size_t data_size, int frame_size, int sample_rate, const ScoreEngineConfig* config) {
    // 参数验证 - 这里的frame_size是半帧大小
    if (base_file == NULL || data_size == 0) {
        set_error(ERROR_FILE_NOT_FOUND);
        return NULL;
    }
    
    if (frame_size <= 0 || sample_rate <= 0) {
        set_error(ERROR_CONFIG_INVALID);
        return NULL;
    }
    
    SE_PRINT("Initializing engine with half frame size = %d, sample rate = %d Hz, data size = %zu\n", 
             frame_size, sample_rate, data_size);
    
    // 加载基准文件
    BaseFileHeader file_header;
    void* file_data = NULL;
    size_t file_data_size = 0;
    
    // 直接使用传入的内存数据，传入实际的数据大小
    int load_result = load_base_file_data(base_file, data_size, &file_header, &file_data, &file_data_size);
    if (load_result != ERROR_SUCCESS) {
        set_error(load_result);
        return NULL;
    }
    
    // 验证基准文件头部
    int validation_result = validate_base_file_header(&file_header, sample_rate, frame_size);
    if (validation_result != ERROR_SUCCESS) {
        free(file_data);
        set_error(validation_result);
        return NULL;
    }
    
    // 打印文件头信息
    print_base_file_header(&file_header);
    
    // 验证文件校验和
    if (file_header.checksum != 0) {  // 只有当校验和不为0时才验证
        if (!verify_file_checksum(&file_header, file_data, file_data_size)) {
            SE_PRINT("Warning: File checksum verification failed\n");
            // 不终止，只是警告
        }
    }
    
    // 分配引擎内存
    ScoreEngine* engine = (ScoreEngine*)malloc(sizeof(ScoreEngine));
    if (!engine) {
        free(file_data);
        set_error(ERROR_OUT_OF_MEMORY);
        return NULL;
    }
    
    // 分配内部状态内存
    InternalState* state = (InternalState*)malloc(sizeof(InternalState));
    if (!state) {
        free(engine);
        free(file_data);
        set_error(ERROR_OUT_OF_MEMORY);
        return NULL;
    }
    
    // 初始化内部状态
    memset(state, 0, sizeof(InternalState));
    state->sample_rate = sample_rate;
    state->frame_size = frame_size * 2;  // 内部保存的是完整帧大小
    printf("Initializing engine: half frame size=%d, full frame size=%d, sample rate=%d\n", 
           frame_size, state->frame_size, state->sample_rate);
    
    // 保存文件数据和头部信息
    state->base_file_cache = file_data;
    memcpy(&state->file_header, &file_header, sizeof(BaseFileHeader));
    state->total_frames = file_header.total_frames;
    
    // 分配各种特征缓冲区
    int buffer_size = state->total_frames + 10; // 总帧数加10作为缓冲
    state->buffer_size = buffer_size;
    
    // 分配特征缓冲区结构体
    state->buffers = create_calculate_score_buffers(buffer_size, state->total_frames);
    if (!state->buffers) {
        free(state);
        free(engine);
        free(file_data);
        set_error(ERROR_OUT_OF_MEMORY);
        return NULL;
    }
    
    // -------- 填充基准特征缓冲区 --------
    BaseFrameData* base_frames = (BaseFrameData*)state->base_file_cache;
    for (int i = 0; i < state->total_frames; ++i) {
        BaseFrameData* bf = &base_frames[i];
        state->buffers->pitch_buffer_base[i]      = bf->pitch;
        state->buffers->energy_buffer_base[i]     = bf->energy;
        state->buffers->brightness_buffer_base[i] = bf->brightness;
        state->buffers->timbre_buffer_base[i]     = bf->timbre;
        state->buffers->rhythm_buffer_base[i]     = bf->rhythm;
        state->buffers->vad_buffer_base[i]        = bf->vad_value;
    }
    
    // 分配前一帧线性幅度谱缓冲区
    int spec_bins = state->frame_size / 2 + 1; // Nyquist 频率以下的点数
    state->prev_spectrum_mag = (float*)malloc(spec_bins * sizeof(float));
    if (!state->prev_spectrum_mag) {
        free(state->buffers);
        free(state);
        free(engine);
        free(file_data);
        set_error(ERROR_OUT_OF_MEMORY);
        return NULL;
    }
    memset(state->prev_spectrum_mag, 0, spec_bins * sizeof(float));
    
    // 分配半帧缓存
    state->prev_half_frame = (float*)malloc(frame_size * sizeof(float));  // 使用半帧大小
    if (!state->prev_half_frame) {
        free(state->buffers);
        free(state->prev_spectrum_mag);
        free(state);
        free(engine);
        free(file_data);
        set_error(ERROR_OUT_OF_MEMORY);
        return NULL;
    }
    memset(state->prev_half_frame, 0, frame_size * sizeof(float));  // 使用半帧大小
    state->has_prev_frame = 0;
    
    // 分配完整帧缓冲区
    state->full_frame = (float*)malloc(state->frame_size * sizeof(float));
    if (!state->full_frame) {
        free(state->prev_half_frame);
        free(state->buffers);
        free(state->prev_spectrum_mag);
        free(state);
        free(engine);
        free(file_data);
        set_error(ERROR_OUT_OF_MEMORY);
        return NULL;
    }
    memset(state->full_frame, 0, state->frame_size * sizeof(float));
    
    // 创建特征集缓存 - 只创建一次，在所有帧处理中复用
    // 这种设计可以避免每帧都创建和释放特征集，显著提高性能
    state->features = create_feature_set(state->frame_size, state->sample_rate);
    if (!state->features) {
        free(state->full_frame);
        free(state->prev_half_frame);
        free(state->buffers);
        free(state->prev_spectrum_mag);
        free(state);
        free(engine);
        free(file_data);
        set_error(ERROR_OUT_OF_MEMORY);
        return NULL;
    }
    
    // 配置复制
    if (config) {
        memcpy(&state->config, config, sizeof(ScoreEngineConfig));
    } else {
        // 使用默认配置
        state->config.enabled_dimensions = SCORE_ALL;
        state->config.style = SONG_STYLE_POP;
        state->config.difficulty = DIFFICULTY_NORMAL;
        state->config.custom_weights = NULL;
        state->config.custom_factors = NULL;
    }
    
    // 初始化算法状态
    // TODO: 初始化算法状态
    
    // 设置引擎参数
    engine->base_file = state->base_file_cache; // 存储文件内容指针
    engine->frame_size = state->frame_size;
    engine->sample_rate = state->sample_rate;
    engine->internal_state = state;
    engine->data_offset = sizeof(BaseFileHeader) + state->total_frames * sizeof(BaseFrameData); // 扩展区起始偏移
    SE_PRINT("Extension data offset (bytes): %ld\n", engine->data_offset);

    set_error(ERROR_SUCCESS);
    SE_PRINT("Score engine initialized successfully\n");
    return engine;
}

// 获取初始化错误码
int get_init_error(void) {
    return last_error_code;
}

// 实时评分接口函数
int score_audio_frame(ScoreEngine* engine, const float* audioFrame, 
                      int frameIndex, ScoreResult* result, float* spectrum) {
    // 参数验证
    if (!engine || !engine->internal_state) {
        set_error(ERROR_ENGINE_NOT_INITIALIZED);
        return ERROR_ENGINE_NOT_INITIALIZED;
    }
    
    if (!audioFrame) {
        set_error(ERROR_AUDIO_FRAME_INVALID);
        return ERROR_AUDIO_FRAME_INVALID;
    }
    
    if (!result) {
        set_error(ERROR_CONFIG_INVALID);
        return ERROR_CONFIG_INVALID;
    }
    
    InternalState* state = (InternalState*)engine->internal_state;
    
    // 初始化结果结构体为0
    memset(result, 0, sizeof(ScoreResult));
    
    // 使用预分配的完整帧缓冲区，而不是每次都分配新的
    float* full_frame = state->full_frame;
    
    // 组合帧数据
    if (state->has_prev_frame) {
        // 组合上一个半帧和当前半帧形成完整帧
        memcpy(full_frame, state->prev_half_frame, state->frame_size / 2 * sizeof(float));
        memcpy(full_frame + state->frame_size / 2, audioFrame, state->frame_size / 2 * sizeof(float));
        
    } else {
        // 首次调用，仅复制当前数据，前半部分为0
        memset(full_frame, 0, state->frame_size / 2 * sizeof(float));
        memcpy(full_frame + state->frame_size / 2, audioFrame, state->frame_size / 2 * sizeof(float));
        SE_PRINT("Processing first half-frame #%d (first half is zeros)\n", frameIndex);
    }
    
    // 保存当前半帧用于下次处理
    memcpy(state->prev_half_frame, audioFrame, state->frame_size / 2 * sizeof(float));
    state->has_prev_frame = 1;
    
    // 预处理音频帧
    // TODO: 实现音频预处理 - 使用完整帧数据full_frame进行处理，而非原始audioFrame
    
    // 特征提取 - 使用保存的特征集，避免重复创建和释放
    // 每次调用都会重新使用同一个特征集对象，覆盖上一帧的数据
    extract_features(full_frame, state->frame_size, state->features);
    
    // 存储提取的特征到缓冲区
    if (frameIndex >= 0 && frameIndex < state->buffer_size) {
        // 存储各种特征到对应的缓冲区
        state->buffers->pitch_buffer[frameIndex] = state->features->pitch;
        state->buffers->energy_buffer[frameIndex] = state->features->energy;
        state->buffers->brightness_buffer[frameIndex] = state->features->brightness;
        state->buffers->timbre_buffer[frameIndex] = state->features->timbre_features;
        
        // 计算频谱通量 (简化版本，实际应该计算相邻帧频谱的差异)
        float flux = 0.0f;
        if (frameIndex > 0) {
            // 使用线性幅度谱计算频谱通量
            int half_frame_size = state->frame_size / 2 + 1; // Nyquist频率以下的频点数量
            for (int i = 0; i < half_frame_size; i++) {
                // 计算当前帧与前一帧线性幅度谱的差异
                // 只考虑能量增加的部分(正差值)
                float diff = state->features->spectrum_mag[i] - state->prev_spectrum_mag[i];
                if (diff > 0.0f) {
                    flux += diff;
                }
            }
            // 归一化
            flux /= half_frame_size;
        }
        state->buffers->flux_buffer[frameIndex] = flux;
        
        // 在计算频谱通量后更新前一帧线性幅度谱，为下一帧计算准备
        int half_frame_size = state->frame_size / 2 + 1;
        memcpy(state->prev_spectrum_mag, state->features->spectrum_mag, 
              half_frame_size * sizeof(float));
        
        // 更新当前处理的帧索引
        state->current_frame = frameIndex + 1;
    }
    
    // 填充结果 - 从特征集中提取值填充到结果中
    // 数据流向: 特征集 -> 评分结果
    result->frame_feature.frame_index = frameIndex;
    result->frame_feature.vad_value = state->features->vad_value;
    result->frame_feature.pitch = state->features->pitch;
    result->frame_feature.energy = state->features->energy;
    result->frame_feature.brightness = state->features->brightness;
    result->frame_feature.timbre = state->features->timbre_features;

    // 从基准文件缓存中读取频谱数据到前256点
    if (state && state->base_file_cache) {
        // 计算基准帧数据的大小和偏移量
        size_t frame_data_size = sizeof(BaseFrameData);
        
        // 确保帧索引在有效范围内
        if (frameIndex >= 0 && frameIndex < state->total_frames) {
            // 计算当前帧在缓存中的偏移位置
            size_t frame_offset = frameIndex * frame_data_size;
            
            // 获取基准帧数据指针
            BaseFrameData* base_frame = (BaseFrameData*)((char*)state->base_file_cache + frame_offset);
            
            result->base_frame_feature.frame_index = base_frame->frame_index;
            result->base_frame_feature.vad_value = base_frame->vad_value;
            result->base_frame_feature.pitch = base_frame->pitch;
            result->base_frame_feature.energy = base_frame->energy;
            result->base_frame_feature.brightness = base_frame->brightness;
            result->base_frame_feature.timbre = base_frame->timbre;

            // SE_PRINT("result->base_frame_feature.frame_index %d\n",result->base_frame_feature.frame_index);
            // SE_PRINT("result->base_frame_feature.vad_value %f\n",result->base_frame_feature.vad_value);
            // SE_PRINT("result->base_frame_feature.pitch %f\n",result->base_frame_feature.pitch);
            // SE_PRINT("result->base_frame_feature.energy %f\n",result->base_frame_feature.energy);
            // SE_PRINT("result->base_frame_feature.brightness %f\n",result->base_frame_feature.brightness);
            // SE_PRINT("result->base_frame_feature.timbre %f\n",result->base_frame_feature.timbre);

            if(spectrum){
            // 初始化频谱数据为0
                memset(spectrum, 0, 512 * sizeof(float));         // 将基准帧的频谱数据复制到spectrum的前256个点
                for (int i = 0; i < 256; i++) {
                    // 直接复制整数值，不转换为浮点数
                    spectrum[i] = (float)base_frame->spectrum[i];
                }
                // 后256点填充当前帧从特征集中提取的频谱数据
                for (int i = 0; i < 256; i++) {
                    spectrum[i + 256] = state->features->spectrum[i];
        //            LOGD("spectrum [%d] %f -> %f", i + 256 , state->features->spectrum[i],spectrum[i + 256]);
                }
            }

        } else {
            SE_PRINT("Warning: Frame index %d out of range (0-%d)\n", 
                    frameIndex, state->total_frames - 1);
        }
    } else {
        SE_PRINT("Warning: No base file cache available\n");
    }
    
    // 评分计算 - 使用提取的特征计算分数
    // 调用calculate_overall_score计算当前帧的评分
    if (frameIndex >= 0 && frameIndex < state->buffer_size) {
        // 直接使用引擎配置进行评分计算
        int score_result = calculate_overall_score(
            state->buffers,         // 特征缓冲区
            frameIndex,             // 当前帧索引
            result,                 // 评分结果
            &state->config          // 引擎配置
        );
        
        if (score_result != ERROR_SUCCESS) {
            SE_PRINT("Warning: Failed to calculate score for frame %d\n", frameIndex);
            // 不返回错误，继续处理
        }
    } else {
        SE_PRINT("Warning: Frame index %d out of range for scoring\n", frameIndex);
    }
    
    return ERROR_SUCCESS;
}

// 释放评分引擎资源
void release_score_engine(ScoreEngine* engine) {
    if (!engine) {
        return;
    }
    
    // 释放内部状态
    if (engine->internal_state) {
        InternalState* state = (InternalState*)engine->internal_state;
        
        // 释放算法状态
        if (state->algorithm_state) {
            free(state->algorithm_state);
        }
        
        // 释放特征缓冲区
        if (state->feature_buffer) {
            free(state->feature_buffer);
        }
        
        // 释放特征集 - 只有一个特征集实例，在引擎释放时一并释放
        if (state->features) {
            free_feature_set(state->features);
        }
        
        // 释放基准文件缓存
        if (state->base_file_cache) {
            free(state->base_file_cache);
        }
        
        // 释放半帧缓存
        if (state->prev_half_frame) {
            free(state->prev_half_frame);
        }
        
        // 释放完整帧缓冲区
        if (state->full_frame) {
            free(state->full_frame);
        }
        
        // 释放各种特征缓冲区
        if (state->buffers) {
            free_calculate_score_buffers(state->buffers);
        }
        
        if (state->prev_spectrum_mag) {
            free(state->prev_spectrum_mag);
        }
        
        free(state);
    }
    
    // 释放引擎结构体
    free(engine);
} 